package org.exhaust.framework.net.test.protocol.server.udp.decoder;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import org.exhaust.framework.net.common.protocol.decoder.ByteBufDecoderHelper;
import org.exhaust.framework.net.test.protocol.server.udp.AbstractClientMsg;
import org.exhaust.framework.net.test.protocol.server.udp.client.ClientFrameHeader;
import org.exhaust.framework.net.test.protocol.server.udp.client.HelloMsg;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ClientDemoMsgDecoderHelper implements ByteBufDecoderHelper<AbstractClientMsg> {

    private static final Map<Integer, Class<? extends AbstractClientMsg>> clazzMap = new ConcurrentHashMap<>(100);

    static {
        clazzMap.put(HelloMsg.MSG_TYPE, HelloMsg.class);
    }

    @Override
    public AbstractClientMsg decode(ChannelHandlerContext ctx, ByteBuf in) {
        int msgType = in.readUnsignedShort();
        long length = in.readUnsignedInt();
        ClientFrameHeader header = new ClientFrameHeader();
        header.setCmdType(msgType);
        header.setLength((int) length);
        final Class<? extends AbstractClientMsg> aClass = clazzMap.get(msgType);
        AbstractClientMsg abstractClientMsg = null;
        try {
            abstractClientMsg = aClass.newInstance();
            abstractClientMsg.decode(in, header);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return abstractClientMsg;
    }
}
